package 反射;

import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/*
    类加载器的作用:
        类加载的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口
        类缓存:标准的JavaSE类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间,不过JVM垃圾回收机制可以回收这些Class对象

       引导类加载器:用C++编写的,是JVM自带的类加载器,负责Java平台核心库,用来装载核心类库,该加载器无法直接获取
       扩展类加载器:负责jre/lib/ext目录下的jar包或 – D java.ext.dirs 指定目录下的jar包装入工作库
       系统类加载器:负责java –classpath 或 –D java.class.path所指的目录下的类与jar包装入工作,是最常用的加载器
 */
public class ClassLoader04 {

    @Test
    public void test1(){
        //获取当前类的类加载器
        ClassLoader classLoader = ClassLoader04.class.getClassLoader();
        //该加载器即为系统类加载器
        System.out.println(classLoader);

        //获取当前类的加载器的上一层(扩展类加载器)
        ClassLoader parent1 = classLoader.getParent();
        System.out.println(parent1);

        //获取上一层加载器的上一层,即为引导类加载器,输出值为null,代表该加载器无法获取,该加载器主要负责加载Java的核心类库,无法加载自定义类
        ClassLoader parent2 = parent1.getParent();
        System.out.println(parent2);

        //String类属于Java的核心类,他的类加载器即为引导类加载器,但无法获取
        ClassLoader stringClassLoader = String.class.getClassLoader();
        System.out.println(stringClassLoader);
    }

    /*
        使用ClassLoader加载配置文件
            类加载器的一个主要方法:getResourceAsStream(String str):获取类路径下的指定文件的输入流
     */
    @Test
    public void test2() throws IOException {
        Properties properties = new Properties();
        //获取系统类加载器
        ClassLoader classLoader = ClassLoader04.class.getClassLoader();
        //获取配置文件的输入流
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("jdbc1.properties"); //配置文件默认在当前module的src下

        properties.load(resourceAsStream);

        String name = properties.getProperty("name");
        String password = properties.getProperty("password");
        System.out.println("name:" + name);
        System.out.println("password:" + password);
    }

}
